package com.jswdwsx.esign.service

import com.jswdwsx.esign.cloud.enums.SealTypeEnum
import com.jswdwsx.esign.commom.ResEnum
import com.jswdwsx.esign.entity.SealPO
import com.jswdwsx.esign.entity.UserPO
import com.jswdwsx.esign.protocol.EsignApi
import com.jswdwsx.esign.protocol.request.PersonalSealReq
import com.jswdwsx.esign.protocol.request.SealImageReq
import com.jswdwsx.esign.protocol.request.UserReq
import com.jswdwsx.esign.protocol.response.SealImageResp
import com.jswdwsx.esign.protocol.response.UpdateUserResp
import com.jswdwsx.esign.repo.SealRepository
import com.jswdwsx.esign.repo.UserRepository
import com.jswdwsx.esign.service.dto.CreateAccountDTO
import com.jswdwsx.esign.util.Id
import com.jswdwsx.esign.util.base64Image
import org.slf4j.LoggerFactory.getLogger
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import java.util.*


@Service
class AccountService(
    private val esignApi: EsignApi,
    private val esignApiWithIdentity: EsignApi,
    private val userRepository: UserRepository,
    private val sealRepository: SealRepository
) {

    private val logger = getLogger(AccountService::class.java)

    fun queryAccount(accountId: String): UpdateUserResp {
        val esignResp = esignApi.queryAccount(accountId)
        logger.info("查询个人账号响应：$esignResp")
        return esignResp.data(ResEnum.CallEsignUserQueryFail)
    }

    fun createAccount(userReq: UserReq): UserPO {

        val esignResp = esignApi.createAccount(userReq)
        logger.info("call esign create account api ,esignResp:$esignResp")
        val userResp = esignResp.data(ResEnum.CallEsignUserCreateFail)
        return userRepository.save(
            UserPO(
                userReq.thirdPartyUserId,
                userReq.name,
                userResp.accountId,
                userReq.idType,
                userReq.idNumber,
                userReq.mobile,
                userReq.email
            )
        )
    }

    fun updateAccount(user: UserPO): UserPO {
        val esignResp = esignApi.updateAccount(user.accountId, user)
        logger.info("调用E签宝更新 account 接口 ,esignResp:$esignResp")
        val res = esignResp.data(ResEnum.CallEsignUserUpdateFail)
        return userRepository.save(
            user.copy(
                name = res.name,
                accountId = res.accountId,
                idType = res.idType,
                idNumber = res.idNumber,
                mobile = res.mobile,
                email = res.email
            )
        )
    }

    /**
     * 获取签署人，若找不到直接向e签宝注册
     */
    fun checkAndCreateUser(createAccountDTO: CreateAccountDTO): UserPO {
        val signerIdType = createAccountDTO.signerIdType
        val signerIdNumber = createAccountDTO.signerIdNumber
        // 有姓名身份证就数据库找一找
        if (signerIdType != null && signerIdNumber != null) {
            val userList = userRepository.findAllByIdTypeAndIdNumber(signerIdType, signerIdNumber)
            if (userList.isNotEmpty()) {
                userList[0].let {
                    // 已创建，检查是否需要更新 暂时只更新电话
                    if (createAccountDTO.signerMobile != it.mobile) {
                        it.mobile = createAccountDTO.signerMobile
                        updateAccount(it)
                    }
                    return it
                }
            }
        }
        // 没有有姓名身份证 或者没找到 就直接向E签宝注册
        val userReq = UserReq(
            "${Id.USER.prefix}${UUID.randomUUID()}",
            createAccountDTO.signerName,
            createAccountDTO.signerIdType,
            createAccountDTO.signerIdNumber,
            createAccountDTO.signerMobile
        )
        return createAccount(userReq)
    }

    /**
     * 创建图片印章
     */
    fun createSealImage(accountId: String, file: MultipartFile): SealImageResp {
        val base64Image = base64Image(file)
        val sealImageReq = SealImageReq(
            data = base64Image,
            type = "BASE64"
        )
        val esignResp = esignApi.createSealImage(accountId, sealImageReq)
        logger.info("调用E签宝创建图片印章接口 ,esignResp:$esignResp")
        return esignResp.data(ResEnum.CallEsignCreateSealImageFail)
    }

    /**
     * 设置静默签署
     */
    fun setSilentSign(accountId: String): Boolean {

        // 同时为两个projectId设置静默签署权限
        val esignResp = esignApi.setSilentSign(accountId)
        logger.info("nonIdentity调用E签宝设置静默签署接口 ,esignResp:$esignResp")

        val esignResp2 = esignApiWithIdentity.setSilentSign(accountId)
        logger.info("Identity调用E签宝设置静默签署接口 ,esignResp:$esignResp2")

        return esignResp.isSuccess && esignResp2.isSuccess
    }

    fun checkAndCreateDefaultPersonalSeal(user: UserPO): SealPO {
        return sealRepository.findByOwnerAndName(user.accountId, DEFAULT_SEAL_NAME)
            ?: createTemplateSeal(
                user.accountId, PersonalSealReq(
                    alias = DEFAULT_SEAL_NAME,
                    color = "RED",
                    type = "RECTANGLE"
                )
            )
    }

    fun createTemplateSeal(accountId: String, personalSealReq: PersonalSealReq): SealPO {

        val esignResp = esignApi.createPersonalSeal(accountId, personalSealReq)
        val sealResp = esignResp.data(ResEnum.CallEsignPersonalSealCreateFail)
        return sealRepository.save(
            SealPO(
                esignSealId = sealResp.sealId!!,
                fileKey = sealResp.fileKey,
                owner = accountId,
                type = SealTypeEnum.PERSONAL,
                name = personalSealReq.alias
            )
        )
    }

    companion object {
        private const val DEFAULT_SEAL_NAME = "默认矩形印章"
    }
}
